package com.neusoft.databus.core.controller;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.neusoft.bizcore.common.cache.CacheService;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.databus.common.bean.ServiceRouterBean;
import com.neusoft.databus.common.connection.AbstractConnection;
import com.neusoft.databus.common.connection.ConnectionFactory;
import com.neusoft.databus.common.connection.SerialConnection;
import com.neusoft.databus.common.connection.SocketConnection;
import com.neusoft.databus.common.constant.DatabusConstant;
import com.neusoft.databus.common.dto.ResourceDTO;
import com.neusoft.databus.core.constant.DatabusCoreConstant;
import com.neusoft.databus.core.service.ResourceService;

import io.swagger.annotations.Api;

/**
 * 任务控制器
 *
 * @author sunchf
 * @date 2019年1月17日 下午2:16:41
 */

@Api("任务控制器")
@RestController
@RequestMapping(value = "/api/w/jobs")
public class JobController {

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private EurekaClient eurekaClient;

    /**
     * 获取任务采集节点的路由信息
     *
     * @param jobName
     * @return
     */
    @GetMapping("/routes/{group}/{name}")
    public ResultDTO<?> getTriggers(@PathVariable String group, @PathVariable String name) {

        final String resourceCode = name;

        final ResourceDTO resource = this.resourceService.findByCode(resourceCode);

        final AbstractConnection connection = ConnectionFactory
                .createConnectionInfo(resource.getGateway().getPhysicalConnType(), resource.getGateway().getConfig());

        String routerIdentifier = "";
        if (connection instanceof SocketConnection) {
            routerIdentifier = ((SocketConnection) connection).getIpAddress();
        } else if (connection instanceof SerialConnection) {
            routerIdentifier = ((SerialConnection) connection).getComValue();
        } else {
            return ResultDTO.failure();
        }

        final ServiceRouterBean bean = new ServiceRouterBean();
        bean.setJobKey(group + "." + name);
        if (this.cacheService.isInCache(DatabusCoreConstant.CACHE_NAME_AGENT_SERVICE_NODE_ROUTE, routerIdentifier)) {
            final String cachedNode =
                    (String) this.cacheService.get(DatabusCoreConstant.CACHE_NAME_AGENT_SERVICE_NODE_ROUTE,
                            routerIdentifier);
            bean.setCurrentNode(cachedNode);
        }

        final Application agentApp = this.eurekaClient.getApplication(DatabusConstant.MICRO_SERVICE_NAME_AGENT);
        final List<String> availableNodes = agentApp.getInstances().stream().map(it -> {
            return it.getId();
        }).collect(Collectors.toList());

        bean.setAvailableNodes(availableNodes);

        return ResultDTO.success(bean);
    }

    /**
     * 切换采集节点
     *
     * @param jobName quartz任务名
     * @param newNode 新节点地址ip@port形式
     * @return
     */
    @PostMapping("/routes/switch/{name}/{newNode}")
    public ResultDTO<?> switchJobNode(@PathVariable String name,
            @PathVariable String newNode) {
        final String resourceCode = name;
        final ResourceDTO resource = this.resourceService.findByCode(resourceCode);

        final AbstractConnection connection = ConnectionFactory
                .createConnectionInfo(resource.getGateway().getPhysicalConnType(), resource.getGateway().getConfig());

        String routerIdentifier = "";
        if (connection instanceof SocketConnection) {
            routerIdentifier = ((SocketConnection) connection).getIpAddress();
        } else if (connection instanceof SerialConnection) {
            routerIdentifier = ((SerialConnection) connection).getComValue();
        } else {
            return ResultDTO.failure();
        }

        this.cacheService.put(DatabusCoreConstant.CACHE_NAME_AGENT_SERVICE_NODE_ROUTE, routerIdentifier,
                newNode.replaceAll("@", ":"));

        return ResultDTO.success();
    }

}
